﻿//-----------------------------------------------------------------------------------------------------------
// Wbfs Engine (WBFSe) Project by Omega Frost 
// http://wbfse.codeplex.com/
//
// WBFSe is Licensed under the terms of the 
// Microsoft Reciprocal License (Ms-RL)
//-----------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using WBFSe.Attributes;
using WBFSe.IO;

namespace WBFSe.FormatApi
{
    /// <summary>
    /// Format creator used by the engine
    /// </summary>
    public abstract class WbfsCreator : IDisposable
    {
        // Variables

        protected String lastError;
        protected String path;
        protected List<String> filenames;

        protected int version;

        protected int sectorSize;
        protected UsageTable sectorUsage;

        protected long estimatedSize;

        // Properties

        /// <summary>
        /// String with the last error encountered by the reader
        /// </summary>
        public String LastError
        {
            get { return this.lastError; }
        }

        /// <summary>
        /// Version of the container
        /// </summary>
        public int Version
        {
            get { return this.version; }
        }

        /// <summary>
        /// Location of the container
        /// </summary>
        public String Path
        {
            get { return this.path; }
        }

        /// <summary>
        /// Readonly list of the container files
        /// </summary>
        public IList<String> Filenames
        {
            get { return this.filenames.AsReadOnly(); }
        }

        /// <summary>
        /// Sector size used in the container
        /// </summary>
        public int SectorSize
        {
            get { return this.sectorSize; }
        }

        /// <summary>
        /// Game sectors stored in the container
        /// </summary>
        public UsageTable SectorUsage
        {
            get { return this.sectorUsage; }
        }

        /// <summary>
        /// Estimated physical size of the container
        /// </summary>
        public long EstimatedSize
        {
            get { return this.estimatedSize; }
        }

        // Methods

        /// <summary>
        /// Initializes the creator with the game and container data
        /// </summary>
        /// <param name="directory">The destination directory</param>
        /// <param name="filename">The destination filename (no extension)</param>
        /// <param name="gameInfo">Built information about the disc</param>
        /// <param name="split">Container split information</param>
        /// <exception cref="System.Exception">On operation failure</exception>
        /// <remarks>Do not fail if the sector size is not right
        /// it will be verified and corrected automatically</remarks>
        public abstract void Initialize(String directory, String filename,
            IDiscExtendedInfo gameInfo, SplitInfo split);

        /// <summary>
        /// Sets a new usage table according to desired sector size
        /// </summary>
        /// <param name="usageTable">New sector usage table</param>
        /// <exception cref="System.Exception">On operation failure</exception>
        public abstract void ResetUsageTable(UsageTable usageTable);

        /// <summary>
        /// Generates a stream for writting on the container
        /// </summary>
        /// <returns>Stream</returns>
        /// <exception cref="System.Exception">On operation failure</exception>
        public abstract IWbfsStream CreateStream();

        /// <summary>
        /// Finishes the container
        /// </summary>
        /// <param name="successful">The operation was successful</param>
        /// <exception cref="System.Exception">On operation failure</exception>
        public abstract void End(bool successful);

        /// <summary>
        /// Disposes the container
        /// </summary>
        public abstract void Dispose();
    }
}
